/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "hitrace_invoker.h"

#include <cstddef>
#include <cstdint>

#include "hilog/log_c.h"
#include "hilog/log_cpp.h"
// #include "hitrace/trace.h"
#include "ipc_debug.h"
#include "log_tags.h"
#include "parcel.h"
#include "sys_binder.h"

namespace OHOS {
// the value should be equal to the set of parcel
using namespace OHOS::HiviewDFX;
// static const HiLogLabel TRACE_LABEL = { LOG_CORE, LOG_ID_IPC, "BinderHiTrace" };

// bool HitraceInvoker::IsClientTraced(int32_t handle, uint32_t flags, const HiTraceId &traceId)
// {
//     return (traceId.IsValid() && (handle != 0) &&
//         ((flags & TF_ONE_WAY) ? traceId.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC) : true));
// }

// HiTraceId HitraceInvoker::TraceClientSend(int32_t handle, uint32_t code, Parcel &data, uint32_t &flags,
//     const HiTraceId &traceId)
// {
//     HiTraceId childId = traceId;
//     bool isClientTraced = IsClientTraced(handle, flags, traceId);
//     if (isClientTraced) {
//         childId = HiTraceChain::CreateSpan();
//         // add childid to parcel data
//         uint8_t idBytes[HITRACE_ID_LEN];
//         size_t idLen = (size_t)(childId.ToBytes(idBytes, HITRACE_ID_LEN));
//         if (idLen != HITRACE_ID_LEN) {
//             ZLOGE(TRACE_LABEL, "%{public}s:idLen not correct", __func__);
//             return childId;
//         }

//         size_t oldWritePosition = data.GetWritePosition();
//         if (!data.WriteBuffer(idBytes, idLen)) {
//             ZLOGE(TRACE_LABEL, "%{public}s:Write idBytes fail", __func__);
//             // restore Parcel data
//             data.RewindWrite(oldWritePosition);
//             return childId;
//         }

//         // padded size of traceid
//         if (!data.WriteUint8(data.GetWritePosition() - oldWritePosition)) {
//             ZLOGE(TRACE_LABEL, "%{public}s:Write idLen fail", __func__);
//             // restore Parcel data
//             data.RewindWrite(oldWritePosition);
//             return childId;
//         }
//         // tracepoint: CS(Client Send)
//         HiTraceChain::Tracepoint(HITRACE_TP_CS, childId, "%s handle=%d,code=%u",
//             (flags & TF_ONE_WAY) ? "ASYNC" : "SYNC",
//             handle, code);
//         flags |= TF_HITRACE;
//     }
//     return childId;
// }

// void HitraceInvoker::TraceClientReceieve(int32_t handle, uint32_t code, uint32_t flags, const HiTraceId &traceId,
//     const HiTraceId &childId)
// {
//     if (!(flags & TF_HITRACE)) {
//         return;
//     }
//     bool isClientTraced = IsClientTraced(handle, flags, traceId);
//     if (isClientTraced) {
//         if (!(flags & TF_ONE_WAY)) {
//             // restore thread trace id
//             HiTraceChain::SetId(traceId);
//             // tracepoint: CR(Client Receive)
//             HiTraceChain::Tracepoint(HITRACE_TP_CR, childId, "%s handle=%d,code=%u", "SYNC", handle, code);
//         }
//     }
// }

// void HitraceInvoker::RecoveryDataAndFlag(Parcel &data, uint32_t &flags, size_t oldReadPosition, uint8_t idLen)
// {
//     // restore data
//     data.RewindRead(oldReadPosition);
//     // padded size(4 bytes) of uint8_t
//     data.SetDataSize(data.GetDataSize() - PADDED_SIZE_OF_PARCEL - idLen);
//     flags &= ~(uint32_t)TF_HITRACE;
// }

// bool HitraceInvoker::TraceServerReceieve(int32_t handle, uint32_t code, Parcel &data, uint32_t &flags)
// {
//     bool isServerTraced = (flags & TF_HITRACE) != 0;
//     if (isServerTraced) {
//         size_t oldReadPosition = data.GetReadPosition();
//         // padded size(4 bytes) of uint8_t
//         data.RewindRead(data.GetDataSize() - PADDED_SIZE_OF_PARCEL);
//         // the padded size of traceid
//         uint8_t idLen = data.ReadUint8();
//         if (idLen >= sizeof(HiTraceIdStruct)) {
//             // padded size(4 bytes) of uint8_t
//             data.RewindRead(data.GetDataSize() - PADDED_SIZE_OF_PARCEL - idLen);
//             const uint8_t *idBytes = data.ReadUnpadBuffer(sizeof(HiTraceIdStruct));
//             if (idBytes == nullptr) {
//                 ZLOGE(TRACE_LABEL, "%{public}s:idBytes is null", __func__);
//                 isServerTraced = 0;
//                 RecoveryDataAndFlag(data, flags, oldReadPosition, idLen);
//                 return isServerTraced;
//             }
//             HiTraceId traceId(idBytes, sizeof(HiTraceIdStruct));
//             HiTraceChain::SetId(traceId);
//             // tracepoint: SR(Server Receive)
//             HiTraceChain::Tracepoint(HITRACE_TP_SR, traceId,
//                 "%s handle=%d,code=%u", (flags & TF_ONE_WAY) ? "ASYNC" : "SYNC",
//                 handle, code);
//         }

//         RecoveryDataAndFlag(data, flags, oldReadPosition, idLen);
//     }
//     return isServerTraced;
// }

// void HitraceInvoker::TraceServerSend(int32_t handle, uint32_t code, bool isServerTraced, uint32_t flags)
// {
//     if (isServerTraced) {
//         // tracepoint: SS(Server Send)
//         HiTraceChain::Tracepoint(HITRACE_TP_SS, HiTraceChain::GetId(), "%s handle=%d,code=%u",
//             (flags & TF_ONE_WAY) ? "ASYNC" : "SYNC", handle, code);
//     }
//     HiTraceChain::ClearId();
// }
} // namespace OHOS
